]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
polkitAgent: Disconnect session signal handlers when destroying session
authorPhilip Withnall <withnall@endlessm.com>
Fri, 18 Jan 2019 13:19:32 +0000 (13:19 +0000)
committerFlorian Müllner <florian.muellner@gmail.com>
Thu, 24 Jan 2019 14:48:48 +0000 (14:48 +0000)
Otherwise the session could outlive the dialogue, emit a subsequent
signal, and its callback would reference finalised objects/widgets from
the dialogue. The PolkitSession object is implemented by
libpolkit-gobject, so we have no guarantees about its reference counting
— the session object could keep itself alive in another thread, or be a
singleton. In all likelihood, the session hangs around for longer than
the dialogue due to differences in when the two objects are garbage
collected.

This can be triggered by running `pkexec true` from a gnome-terminal
window, then calling `pkill pkexec` from another terminal (on a
different VT or via SSH). This causes the dialogue to be cancelled by
polkitd.

Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/357

js/ui/components/polkitAgent.js

index 4b2a2cacbf4cc8646dc6ddb9412e9f34c668fa79..4ea4efba4bc31bf64d3c670a2f07b0b70c79db13 100644 (file)
@@ -169,10 +169,10 @@ var AuthenticationDialog = new Lang.Class({
         this.destroySession();
         this._session = new PolkitAgent.Session({ identity: this._identityToAuth,
                                                   cookie: this._cookie });
-        this._session.connect('completed', this._onSessionCompleted.bind(this));
-        this._session.connect('request', this._onSessionRequest.bind(this));
-        this._session.connect('show-error', this._onSessionShowError.bind(this));
-        this._session.connect('show-info', this._onSessionShowInfo.bind(this));
+        this._sessionCompletedId = this._session.connect('completed', this._onSessionCompleted.bind(this));
+        this._sessionRequestId = this._session.connect('request', this._onSessionRequest.bind(this));
+        this._sessionShowErrorId = this._session.connect('show-error', this._onSessionShowError.bind(this));
+        this._sessionShowInfoId = this._session.connect('show-info', this._onSessionShowInfo.bind(this));
         this._session.initiate();
     },
 
@@ -311,6 +311,11 @@ var AuthenticationDialog = new Lang.Class({
             if (!this._completed)
                 this._session.cancel();
             this._completed = false;
+
+            this._session.disconnect(this._sessionCompletedId);
+            this._session.disconnect(this._sessionRequestId);
+            this._session.disconnect(this._sessionShowErrorId);
+            this._session.disconnect(this._sessionShowInfoId);
             this._session = null;
         }
     },